﻿package com.alstudio.module.sns.tencent;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
import java.util.Date;
import java.util.Map;

import org.apache.http.conn.ConnectTimeoutException;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;

import com.alstudio.app.VersionConfig;
import com.alstudio.module.sns.sina.AccessTokenKeeper;
import com.alstudio.utils.android.net.download.ALHttpDownloadListener;
import com.alstudio.utils.android.net.download.ALHttpDownloadManager;
import com.alstudio.utils.android.net.download.ALHttpDownloadTask;
import com.alstudio.utils.android.net.download.ALHttpDownloadTask.ALHttpDownloadErrorCode;
import com.alstudio.utils.encode.ALMd5;
import com.alstudio.utils.log.ALLog;
import com.tencent.connect.UserInfo;
import com.tencent.connect.auth.QQAuth;
import com.tencent.connect.common.Constants;
import com.tencent.qzone.Albums;
import com.tencent.tauth.IRequestListener;
import com.tencent.tauth.IUiListener;
import com.tencent.tauth.Tencent;
import com.tencent.tauth.UiError;
import com.tencent.utils.HttpUtils.HttpStatusException;
import com.tencent.utils.HttpUtils.NetworkUnavailableException;

;
/**
 * Activity必须注册监听getAuthReceiver()才能获取回调
 * 
 */
public class ITencent {
	private static final String TAG = "ITencent";
	public static final int REQUEST_PICK_PICTURE = 1001;
	private static final String CALLBACK = "auth://tauth.qq.com/";

	private String mAppid = "134977989962884";// 申请时分配的appid
	private String mScope = "get_user_info,get_user_profile,add_share,add_topic,list_album,upload_pic,add_album";// 授权范围

	private String mAccessToken, mOpenId;

	private Activity mActivity;

	private OnAuthEventListener mListener;

	private Tencent mTencent;
	
	private UserInfo mInfo;
	
	private Activity tmpUploadImgAct;
	private Bundle tmpOptionalArgs;
	private String tmpImageFile ;
	private OnAuthEventListener tmpOnAuthListener;
	private QQAuth mQQAuth;

	public String getAccessToken() {
		return this.mAccessToken;
	}

	public String getOpenId() {
		return this.mOpenId;
	}

	public void setAccessToken(String accessToken, String openId) {
		this.mAccessToken = accessToken;
		this.mOpenId = openId;
	}

	public void setOnAuthEventListener(OnAuthEventListener listener) {
		mListener = listener;
	}
	public Tencent getTencent(){
		return mTencent;
	}

	/**
	 * @param appId
	 *            : 申请QQ登录成功后，分配给应用的appid
	 * @param scope
	 *            : 请求用户授权时向用户显示的可进行授权的列表
	 * 
	 */
	public ITencent(Activity activity, String appId, String scope) {
		if (appId == null || "".equalsIgnoreCase(appId))
			throw new IllegalArgumentException(
					"You must specify your application ID when instantiating "
							+ "a Tencent object. See README for details.");

		this.mAppid = appId;
		this.mActivity = activity;
		if (scope != null)
			this.mScope = scope;
		// 获取实例对象
		String expires_in = AccessTokenKeeper.readTencentAccessToken(activity)
				.get("expires_in");
		String openid = AccessTokenKeeper.readTencentAccessToken(activity).get(
				"openid");
		String access_token = AccessTokenKeeper
				.readTencentAccessToken(activity).get("access_token");
		mTencent = Tencent.createInstance(mAppid, activity.getApplicationContext());
		mQQAuth = QQAuth.createInstance(mAppid,
				activity.getApplicationContext());
		if (!TextUtils.isEmpty(expires_in) && !TextUtils.isEmpty(openid)
				&& !TextUtils.isEmpty(expires_in)) {
			long nowtime = (Long.parseLong(expires_in) - System
					.currentTimeMillis()) / 1000;
			if (nowtime <= 0) {
				auth(mActivity, mScope, mListener);
			} else {
				mTencent.setOpenId(openid);
				mTencent.setAccessToken(access_token,
						String.valueOf((Long.parseLong(expires_in) - System
								.currentTimeMillis()) / 1000));
			}
		}
	}

	public boolean satisfyConditions() {
		// return mAccessToken != null && mAppid != null && mOpenId != null
		// && !mAccessToken.equals("") && !mAppid.equals("")
		// && !mOpenId.equals("");
		return mTencent.isSessionValid();
	}

	/**
	 * 增量授权
	 */
	public void auth(Activity activity, String scope,
			OnAuthEventListener listener) {

		mTencent.reAuth(activity, scope, new BaseUiListener(listener));

	}

	public void authorizeCallBack(int requestCode, int resultCode, Intent data) {
		if (mTencent != null) {
			mTencent.onActivityResult(requestCode, resultCode, data);
			
		}
	}

	public void logout(Activity activity) {

	}

	public void login(Activity activity, String scop,
			OnAuthEventListener listener) {
		mTencent.login(activity, scop, new BaseUiListener(listener));
	}

	private class BaseUiListener implements IUiListener {
		private OnAuthEventListener listener = null;

		public BaseUiListener(OnAuthEventListener listener) {
			super();
			this.listener = listener;
			mListener = listener;
		}

		@Override
		public void onCancel() {
			ALLog.e("auth cancel");
			if (listener != null) {
				listener.onCancel();

			}
		}


		@Override
		public void onError(UiError e) {
			ALLog.e("onError:" + "code:" + e.errorCode + ", msg:"
					+ e.errorMessage + ", detail:" + e.errorDetail);
			if (listener != null) {
				listener.onAuthFailed(e.errorCode, e.errorDetail);
			}
		}

		@Override
		public void onComplete(Object response) {
			// TODO Auto-generated method stub

			try {
				JSONObject jsonObj = (JSONObject) response;

				mOpenId = jsonObj.getString("openid");
				mAccessToken = jsonObj.getString("access_token");
				String expires_in = jsonObj.getString("expires_in");
				Log.i(TAG, String.format(
						"openid: %s, access_token : %s, expires_in : %s",
						mOpenId, mAccessToken, expires_in));
				expires_in = String.valueOf(System.currentTimeMillis()
						+ Long.parseLong(expires_in) * 1000);
				AccessTokenKeeper.keepTencentAccessToken(mActivity,
						mAccessToken, expires_in, mOpenId);
				if (listener != null) {
					listener.onAuthSuccess();
				}
			} catch (JSONException e) {
				e.printStackTrace();
			}
		}
	}

	public interface OnAuthEventListener {

		// 取消
		void onCancel();

		// 授权验证成功
		void onAuthSuccess();

		// 授权验证失败
		void onAuthFailed(int ret, String msg);

		void doComplete(JSONObject response, Object state);

	}

	public interface Callback {
		void onSuccess(Object obj);

		void onError(int ret, String msg);
	}

	/**
	 * 下载图片
	 * 
	 * @param url
	 *            : 图片url地址
	 * @return
	 */
	public String downloadPicture(String url) {
		path = VersionConfig.IMAGE_PATH + "/" + ALMd5.encode(url);
		if (new File(path).exists()) {
			return path;
		}
		ALHttpDownloadManager.startDownload(mActivity, url, VersionConfig.IMAGE_PATH,
				ALMd5.encode(url), alHttpDownloadListener);
		return null;
	}

	String path = "";
	ALHttpDownloadListener alHttpDownloadListener = new ALHttpDownloadListener() {

		@Override
		public void onUpdateProcess(ALHttpDownloadTask info) {

		}

		@Override
		public void onPreDownload(String name) {

		}

		@Override
		public void onDownloadFinish(ALHttpDownloadTask info) {
			path = info.getFilePath();
			

			
			if(tmpUploadImgAct != null && tmpOptionalArgs != null && !TextUtils.isEmpty(tmpImageFile) && tmpOnAuthListener != null){
				uploadImage(tmpUploadImgAct, tmpImageFile, tmpOptionalArgs, tmpOnAuthListener);
				tmpUploadImgAct = null;
				tmpOptionalArgs = null;
				tmpImageFile = null;
				tmpOnAuthListener = null;
			}
		}
		

		@Override
		public void onDownloadFail(ALHttpDownloadErrorCode code, String name,ALHttpDownloadTask info) {
			tmpUploadImgAct = null;
			tmpOptionalArgs = null;
			tmpImageFile = null;
			tmpOnAuthListener = null;
		}

	};

	private boolean ready() {
		boolean ready = mTencent.isSessionValid()
				&& mTencent.getOpenId() != null;
		return ready;
	}

	/**
	 * 获取用户登录信息
	 * 
	 * @param callback
	 * @return
	 */
	public boolean getUserInfo(Activity activity, String scope,
			boolean needReAuth, final OnAuthEventListener authListener) {
		if (!satisfyConditions()) {
			return false;
		}

		if (ready()) {

			IUiListener listener = new IUiListener() {

				@Override
				public void onError(UiError e) {
					// TODO Auto-generated method stub
				}

				@Override
				public void onComplete(final Object response) {
					authListener.doComplete((JSONObject) response, null);
				}

				@Override
				public void onCancel() {
					// TODO Auto-generated method stub

				}
			};

			mInfo = new UserInfo(activity, mQQAuth.getQQToken());
			mInfo.getUserInfo(listener);
			// mTencent.requestAsync("user/get_simple_userinfo", null,
			// Constants.HTTP_GET, new BaseApiListener(activity,
			// "get_simple_userinfo", false, listener), null);

		}

		return true;
	}

	public boolean uploadImage(Activity activity, String imageFile,
			Bundle optionalArgs, OnAuthEventListener listener) {
		if (!satisfyConditions()) {
			return false;
		}

		String filePath = "";

		if (imageFile.startsWith("http://")) {
			filePath = downloadPicture(imageFile);
		} else {
			filePath = imageFile;
		}


		String photodesc = "QQ登陆SDK：UploadPic测试" + new Date();// 照片描述，注意照片描述不能超过200个字符。

		String x = "0";// 照片拍摄时的地理位置的经度。请使用原始数据（纯经纬度，0-360）。
		String y = "0";// 照片拍摄时的地理位置的纬度。请使用原始数据（纯经纬度，0-360）。

		photodesc = optionalArgs.getString("photodesc");

		Albums mAlbums = new Albums(activity, mQQAuth.getQQToken());
		mAlbums.uploadPicture(filePath, photodesc, null, x, y,
				new AlbumListListener("upload_pic", true, activity, listener));// 相册id，不填则传到默认相册

		return true;
	}

	/**
	 * 
	 * @author zivonchen
	 * 
	 */
	private class AlbumListListener extends BaseUIListener {
		private String mScope = "all";
		private Boolean mNeedReAuth = false;
		private Activity mActivity;
		OnAuthEventListener listener;

		public AlbumListListener(String scope, boolean needReAuth,
				Activity activity, OnAuthEventListener listener) {
			super(activity);
			this.mScope = scope;
			this.mNeedReAuth = needReAuth;
			this.mActivity = activity;
			this.listener = listener;
		}

		protected void doComplete(JSONObject response, Object state) {
			try {
				int ret = response.getInt("ret");
				if (ret == 100030) {
					if (mNeedReAuth) {
						Runnable r = new Runnable() {
							public void run() {
								mTencent.reAuth(mActivity, mScope,
										new BaseUiListener(mListener));
							}
						};
						mActivity.runOnUiThread(r);
					}
				} else if (ret == 0) {

					listener.doComplete(response, state);
				}
			} catch (JSONException e) {
				e.printStackTrace();
			}

		}

		@Override
		public void onComplete(final Object response) {
			doComplete((JSONObject) response, null);
		}
	}

	/**
	 * 空间分享
	 * 
	 * <p>
	 * 
	 * @param title
	 *            : 必须，feeds的标题， 最长36个中文字，超出部分会被截断。
	 * @param url
	 *            : 必须，分享所在网页资源的链接，点击后跳转至第三方网页，请以http://开头。
	 * @param optionalArgs
	 *            : 可选参数
	 * @param callback
	 *            : 分享结果回调
	 * @return : 请求是否发送成功
	 *         </p>
	 * 
	 *         <p>
	 *         <br/>
	 *         optionalArgs可选参数有 : <br/>
	 *         1. comment :
	 *         用户评论内容，也叫发表分享时的分享理由，禁止使用系统生产的语句进行代替，最长40个中文字，超出部分会被截断。 <br/>
	 *         2. summary : 所分享的网页资源的摘要内容，或者是网页的概要描述，最长80个中文字，超出部分会被截断。 <br/>
	 *         3. images :
	 *         所分享的网页资源的代表性图片链接，请以http://开头，长度限制255字符。多张图片以竖线（|）分隔，目前只有第一张图片有效
	 *         ，图片规格100*100为佳。 <br/>
	 *         4. format :
	 *         定义API返回的数据格式。取值说明：为xml时表示返回的格式是xml；为json时表示返回的格式是json。
	 *         注意：json、xml为小写，否则将不识别。format不传或非xml，则返回json格式数据。 <br/>
	 *         5. source :分享的场景，取值说明：1.通过网页 2.通过手机 3.通过软件 4.通过IPHONE 5.通过 IPAD。
	 *         <br/>
	 *         6. type : 分享内容的类型。4表示网页；5表示视频（type=5时，必须传入playurl）。 <br/>
	 *         7. playurl : 长度限制为256字节。仅在type=5的时候有效，表示视频的swf播放地址。 <br/>
	 *         8. site : 分享的来源说明，对应上文接口说明的6。 <br/>
	 *         9. nswb : 值为1时，表示分享不默认同步到微博，其他值或者不传此参数表示默认同步到微博。
	 *         </p>
	 */
	public boolean shareQZone(Activity activity, String title, String url,
			Map<String, String> optionalArgs, OnAuthEventListener listener) {
		if (title == null || url == null || "".equals(title) || "".equals(url))
			throw new IllegalArgumentException(
					"title and url can't be null or \"\".");

		if (!satisfyConditions()) {
			return false;
		}

		Bundle parmas = new Bundle();
		parmas.putString("title", title);
		parmas.putString("url", url);

		if (optionalArgs != null) {
			for (String key : optionalArgs.keySet()) {
				String value = optionalArgs.get(key);

				if (value != null || "".equals(value)) {
					parmas.putString(key, value);
				}
			}
		}

		mTencent.requestAsync("GRAPH_ADD_SHARE", parmas,
				Constants.HTTP_POST, new BaseApiListener(activity, "add_share",
						true, listener), null);

		return true;
	}

	private class BaseApiListener implements IRequestListener {
		private String mScope = "all";
		private Boolean mNeedReAuth = false;
		private Activity activity = null;
		private OnAuthEventListener mListener = null;

		public BaseApiListener(Activity activity, String scope,
				boolean needReAuth, OnAuthEventListener listener) {
			this.activity = activity;
			mScope = scope;
			mNeedReAuth = needReAuth;
			this.mListener = listener;
		}

		// @Override
		// public void onComplete(final JSONObject response, Object state) {
		// doComplete(response, state);
		// }

		protected void doComplete(JSONObject response, Object state) {
			try {
				int ret = response.getInt("ret");
				if (ret == 100030) {
					if (mNeedReAuth) {
						Runnable r = new Runnable() {
							public void run() {
								mTencent.reAuth(activity, mScope,
										new BaseUiListener(mListener));
							}
						};
						activity.runOnUiThread(r);
					}
				} else if (ret == 0) {

					mListener.doComplete(response, state);
				}
				// azrael 2/1注释掉了, 这里为何要在api返回的时候设置token呢,
				// 如果cgi返回的值没有token, 则会清空原来的token
				// String token = response.getString("access_token");
				// String expire = response.getString("expires_in");
				// String openid = response.getString("openid");
				// mTencent.setAccessToken(token, expire);
				// mTencent.setOpenId(openid);
			} catch (JSONException e) {
				e.printStackTrace();
			}

		}

		@Override
		public void onComplete(JSONObject response) {
			// TODO Auto-generated method stub
			doComplete(response, null);

		}

		@Override
		public void onConnectTimeoutException(ConnectTimeoutException arg0) {
			// TODO Auto-generated method stub

		}

		@Override
		public void onHttpStatusException(HttpStatusException arg0) {
			// TODO Auto-generated method stub

		}

		@Override
		public void onIOException(IOException arg0) {
			// TODO Auto-generated method stub

		}

		@Override
		public void onJSONException(JSONException arg0) {
			// TODO Auto-generated method stub

		}

		@Override
		public void onMalformedURLException(MalformedURLException arg0) {
			// TODO Auto-generated method stub

		}

		@Override
		public void onNetworkUnavailableException(
				NetworkUnavailableException arg0) {
			// TODO Auto-generated method stub

		}

		@Override
		public void onSocketTimeoutException(SocketTimeoutException arg0) {
			// TODO Auto-generated method stub

		}

		@Override
		public void onUnknowException(Exception arg0) {
			// TODO Auto-generated method stub

		}
	}
	
}